package agent

import (
	"context"
	"errors"
	"fmt"
	"math"
	"strconv"
	"time"

	"gitee.com/liuxuezhan/ar-platform/base-common/headInfo"
	"gitee.com/liuxuezhan/ar-platform/base-common/uuid"
	"gitee.com/liuxuezhan/ar-platform/rpc-client/agentClient/rpc"
	assetsRpc "gitee.com/liuxuezhan/ar-platform/rpc-client/assetsClient/rpc"
	"github.com/zeromicro/go-zero/core/logc"

	"gitee.com/liuxuezhan/ar-platform/admin-api/internal/svc"
	"gitee.com/liuxuezhan/ar-platform/admin-api/internal/types"

	"github.com/zeromicro/go-zero/core/logx"
)

const commissionsPercent = 2

type DoManualRebatesLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

// 手动返佣--执行手动返佣
func NewDoManualRebatesLogic(ctx context.Context, svcCtx *svc.ServiceContext) *DoManualRebatesLogic {
	return &DoManualRebatesLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *DoManualRebatesLogic) DoManualRebates(req *types.ManualRebatesReq) (resp *types.IsSuccessInfo, err error) {
	var (
		dateString     string
		opreatorUserId int64

		batchSize int64 = 100
		totalPage int

		_successIds = make([]int64, 0)
		_failIds    = make([]int64, 0)
		_doStatus   int64
	)

	// 参数解析: req.Data utc时间戳
	dateString = time.Unix(((req.Date)/1000)+(8*3600), 0).Format("2006-01-02")
	// location, err := time.LoadLocation("Asia/Shanghai")
	// if err != nil {
	//	logc.Error(l.ctx, err)
	//	return nil, err
	// }
	// dateString = time.Unix(int64(req.Date/1000), 64).In(location).Format(time.DateOnly)

	// 操作用户id
	opreatorUserId = headInfo.GetTokenUid(l.ctx)
	if opreatorUserId < 1 {
		return nil, errors.New("invalid token")
	}

	// 查询开启返佣开关、 已经计算佣金..., 还没有返还佣金的所有会员
	_rpcReq := &rpc.GetManualRebateCommissionUserListReq{
		Date:     dateString,
		Page:     1,
		PageSize: 1,
	}
	// 总数
	_rpcResp, err := l.svcCtx.AgentRPC.GetManualRebateCommissionUserList(l.ctx, _rpcReq)
	if err != nil {
		logc.Error(l.ctx, err)
		return nil, err
	}

	// 记录执行结果
	defer func() {
		if _doStatus == 0 {
			if len(_failIds) == 0 {
				// 全部失败
				_doStatus = 2
			} else {
				// 部分成功、部分失败
				_doStatus = 3
			}
		}
		_remark := ""
		if err != nil {
			_remark = err.Error()
		}
		if err := recover(); err != nil {
			logc.Error(l.ctx, err)
			_remark = err.(string)
			_doStatus = 2
		}
		l.svcCtx.AgentRPC.AddManualRebateCommissionRecords(l.ctx, &rpc.AddManualRebateCommissionRecordsReq{
			Date:       dateString,
			UserId:     opreatorUserId,
			Status:     _doStatus,
			SuccessIds: _successIds,
			FailIds:    _failIds,
			Remark:     _remark,
		})
	}()

	// 执行返佣
	if _rpcResp == nil {
		_doStatus = 1
		return nil, nil
	}
	totalPage = int(math.Ceil(float64(_rpcResp.Total) / float64(batchSize)))

	// 分页处理
	for i := range totalPage {
		rpcReq := &rpc.GetManualRebateCommissionUserListReq{
			Date:     dateString,
			Page:     int64(i + 1),
			PageSize: batchSize,
		}

		// 获取符合返佣条件的会员列表
		rpcResp, err := l.svcCtx.AgentRPC.GetManualRebateCommissionUserList(l.ctx, rpcReq)
		if err != nil {
			logx.Error(l.ctx, err)
			return nil, err
		}

		for _, v := range rpcResp.List {
			// 实际派佣, 精度到小数点后两位
			commissions, err := strconv.ParseFloat(fmt.Sprintf("%.*f", commissionsPercent, v.ComputationalRebatesAmount), 64)
			if err != nil {
				logc.Error(l.ctx, err)
				return nil, err
			}

			_uuid := uuid.GenUUID().String()
			// 执行资产增加
			assetsIncreaseRpcReq := &assetsRpc.BalanceIncreaseRequest{
				UserId:      v.UserId,
				Amount:      commissions,
				OperatorId:  opreatorUserId,
				TypeId:      104,
				SourceId:    _uuid,
				Description: "rebates commission",
			}
			increase, err := l.svcCtx.AssetsRpc.User.BalanceIncrease(l.ctx, assetsIncreaseRpcReq)
			if err != nil {
				logc.Error(l.ctx, err)
				return nil, err
			}

			txId := increase.Id
			// 执行返佣
			_agentRpcReq := &rpc.ManualRebateCommissionReq{
				Date:                 dateString,
				UserId:               v.UserId,
				OperateUserId:        opreatorUserId,
				ProvideRebatesAmount: commissions,
				TxId:                 txId,
			}
			_, err = l.svcCtx.AgentRPC.ManualRebateCommission(l.ctx, _agentRpcReq)
			if err != nil {
				logc.Error(l.ctx, err)
				assetsDecreaseRpcReq := &assetsRpc.BalanceDecreaseRequest{
					UserId:      v.UserId,
					Amount:      commissions,
					OperatorId:  opreatorUserId,
					TypeId:      104,
					SourceId:    _uuid,
					Description: "rebates commission",
				}
				_, err1 := l.svcCtx.AssetsRpc.User.BalanceDecrease(l.ctx, assetsDecreaseRpcReq)
				if err1 != nil {
					_failIds = append(_failIds, v.Id)
					logx.Error(l.ctx, "DoManualRebates err: ", err)
					return nil, err
				}
				return nil, err
			}
			_successIds = append(_successIds, v.Id)
		}
	}

	// 全部成功
	_doStatus = 1

	return
}
